package zhuzx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.github.dadiyang.equator.Equator;
import com.github.dadiyang.equator.GetterBaseEquator;
import com.sun.management.OperatingSystemMXBean;
import lombok.Data;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.zhuzx.util.*;
import sun.nio.ch.DirectBuffer;

import javax.swing.*;
import java.io.*;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.GZIPOutputStream;

@SuppressWarnings({"unused", "null"})
@Slf4j
public class SandBox {

	public static void main(String[] args) {
		
	}

	/**
	 * Map移除keySet()或者values()中的元素时，会影响Map本身（这个键值对都会被移除）。
	 */
	public static void testMapKeyValueRemove() {
		Map<String,Object> map = new HashMap<>();
		map.put("1", 1);
		map.put("2", 2);
		map.keySet().remove("1");
		map.values().remove(2);
		System.out.println(map);
	}

	/**
	 * 解析泛型类需要传入：new TypeReference<外部类名<内部类名>>(){}
	 */
	public static void testFastJsonParseGenericity() {
		@Data
		class QueryPageParam<T> {
			int currentPage;
			int pageSize;
			T data;
			public QueryPageParam() {
			}
			public QueryPageParam(int currentPage, int pageSize, T data) {
				this.currentPage = currentPage;
				this.pageSize = pageSize;
				this.data = data;
			}
		}
		@Data
		class Po {
			String field1;
			int field2;
			public Po() {
			}
			public Po(String field1, int field2) {
				this.field1 = field1;
				this.field2 = field2;
			}
		}
		Po po = new Po("value1", 222);
		QueryPageParam<Po> param = new QueryPageParam<>(1, 2, po);
		String json = JSON.toJSONString(param);
		System.out.println(json);
		QueryPageParam<Po> parsed = JSON.parseObject(json, new TypeReference<QueryPageParam<Po>>(){});
		System.out.println("提取到了值：" + parsed.data.field1);
	}
	
	public static void testFieldEquator() {
		SecurityProperties.User user1 = new SecurityProperties.User();
		user1.setName("A");
		user1.setPassword("aaa");
		SecurityProperties.User user2 = new SecurityProperties.User();
		user2.setName("A");
		
		Equator equator = new GetterBaseEquator();
		System.out.println(equator.isEquals(user1, user2));

		equator = new GetterBaseEquator(true);
		System.out.println(equator.isEquals(user1, user2));

		equator = new GetterBaseEquator(Arrays.asList("name"), null);
		System.out.println(equator.isEquals(user1, user2));

		equator = new GetterBaseEquator(Arrays.asList("name", "password"), null);
		System.out.println(equator.isEquals(user1, user2));

		user2.setName(null);
		user2.setRoles(Arrays.asList("111", "222", "333"));
		System.out.println(equator.getDiffFields(user1, user2));
		equator = new GetterBaseEquator();
		System.out.println(equator.getDiffFields(user1, user2));
	}
	
	/**
	 * 优先级阻塞队列PriorityBlockingQueue可以容纳compare为0的元素，也就是同一个优先级可以有多个元素入队，
	 * 但这些元素互相之间的顺序没有规律，先入队的可能在前可能在后，也就是说，同优先级的元素不保证先入先出或者后入先出。
	 */
	public static void testFixedPriorityBlockingQueue() throws InterruptedException {
		BlockingQueue<Integer> queue = new FixedPriorityBlockingQueue<>(10,
				new Comparator<Integer>() {
					@Override
					public int compare(Integer o1, Integer o2) {
						return o1/10 - o2/10;
					}
				});
		int[] values = {25,333,21,1,339,2,22};
		for (int i : values) {
			queue.put(i);
		}
		while(true) {
			Integer value = queue.poll();
			if (value == null) {
				break;
			}
			System.out.println(value);
		}
	}
	
	public static void needFix() {
		String param = "{\"username\":\"cgcs1\",\"customerNo\":\"234\"}";
//		String String paramCust = MicroUtil.substringByMatesOnRegex(param, "\"customerNo\"\\s*:\\s*\"", "\"");
//		String paramCust = MicroUtil.substringByMates(param, "\"customerNo\":\"", "\"");
//		System.out.println(paramCust);
		
		String paramCust =MicroUtil.subBehind(
				MicroUtil.subBehind(
					MicroUtil.subBehind(param, "\"customerNo\""),
				"\""),
			"\"");
		System.out.println(paramCust);
	}
	
	/**
	 * 非常规地构建数组的几种方式实测，结论：有Array.newInstance和Arrays.asList().toArray()两种支持泛型。
	 */
	public static void testArrayGenerics() {
		Object[] array = new Object[1];
		try {
			System.out.println(((String[]) array)[0]);
		} catch (Exception e) {
			System.out.println("0、常规new出来的Object[]无法强转为String[]，报错信息：" + e.getMessage());
		}
		array = (Object[]) Array.newInstance(String.class, 1);
		array[0] = "1、Array.newInstance，以native方式生成，返回的对象可以先转Object[]再强转String[]。";
		System.out.println(((String[]) array)[0]);
		array = Collections.nCopies(1, "").toArray();
		try {
			System.out.println(((String[]) array)[0]);
		} catch (Exception e) {
			System.out.println("2、Collections.nCopies().toArray()，生成的对象是CopiesList，"
					+ "虽然带泛型，但返回值是个new出来的Object[]，不能强转。");
		}
		array = Arrays.asList("3、Arrays.asList().toArray()，生成的对象是Arrays.ArrayList，"
				+ "返回一个由native的clone方法构建的数组，虽然返回值是写的Object[]，但实际带了泛型类型，可以强转。").toArray();
		System.out.println(((String[]) array)[0]);
		array = new ArrayList<String>(Arrays.asList("")).toArray();
		try {
			System.out.println(((String[]) array)[0]);
		} catch (Exception e) {
			System.out.println("4、普通的new ArrayList().toArray()，返回的是Object[]，"
					+ "由于ArrayList内部的底层数据elementData就是Object[]，所以无法强转。");
		}
	}
	
	public static void testURLEncoder() throws UnsupportedEncodingException {
		String url = "http://10.248.27.91:8081/signature/api/test?param1=2+1&param2=中文参数";
		System.out.println(url);
		System.out.println(URLEncoder.encode(url, "UTF-8"));
		String enc = URLEncoder.encode(url, "iso8859-1");
		System.out.println(enc);
		System.out.println("ios8859编码后用utf8解码：" + URLDecoder.decode(enc, "UTF-8"));
		System.out.println(URLDecoder.decode(url, "UTF-8"));
	}
	
	public static void testRegexPassword() throws UnsupportedEncodingException {
//		String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$";
		String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)([^\\s<>]*[a-zA-Z0-9]+[^\\s<>]*){6,16}$";
		System.out.println("a123".matches(regex));
		System.out.println("a123456781329erwerdfssfd".matches(regex));
		System.out.println("7aaa<aaaaa".matches(regex));
		System.out.println("7aa>aaa".matches(regex));
		System.out.println("1234567890".matches(regex));
		System.out.println("------------");
		regex = "^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\\W]).{6,8}$";
		System.out.println("ds12klf%j".matches(regex));
		System.out.println("we0df!f".matches(regex));
		System.out.println("weadf!f".matches(regex));
		System.out.println("12@2234".matches(regex));
		System.out.println("---------");
		regex = "^[^\\s<>]{9,16}$";
		System.out.println("12345678".matches(regex));
		System.out.println("123456789".matches(regex));
		System.out.println("123456789011111111".matches(regex));
	}
	
	/**
	 * BigDecimal支持科学计数法格式的字符串构建，而BigInteger不支持。
	 */
	public static void testBigDecimalConstructor() {
		String str = "-2.1E-28";
		str = new BigDecimal(str).toPlainString();
		System.out.println(str);
		
		double d1 = Double.MAX_VALUE;
		String d1Str = String.valueOf(d1);
		System.out.println("d1:" + d1Str);
		double d2 = new BigDecimal(d1Str).doubleValue();
		System.out.println("d2:" + d2);
		
		BigInteger i = new BigInteger("2.1E28");
	}
	
	public static void testSetToJson() {
		Set<String> set = new HashSet<>();
		set.add("AAA");
		set.add("BBB");
		set.add("AAA");
		String json = JSON.toJSONString(set);
		System.out.println(JSON.parseObject(json, List.class));
		System.out.println(JSON.parseObject(json, HashSet.class));
	}
	
	public static void testForwardLooking() {
		String regex = "(?<!http(s)?:)//";
		System.out.println(MicroUtil.extractFirst("skdfjhttp://", regex));
		System.out.println(MicroUtil.extractFirst("skdfjhttps://", regex));
		System.out.println(MicroUtil.extractFirst("skdfjhtasdf,//", regex));
		System.out.println(MicroUtil.extractFirst("skdfjhtasttp://", regex));
	}
	
	/**
	 * ''这个符号无法被正则的\s匹配到
	 */
	public static void testUnmatchedCharacter(String[] args) {
		System.out.println(MicroUtil.extractFirst("\"tableDatas\":[{\"unique//判断", ":\\s*[\\[]"));
		System.out.println(FileOperationUtil.bytesToHex("".getBytes(StandardCharsets.UTF_8)));
		System.out.println("".matches("\\s*"));
		System.out.println(" ".matches("\\s*"));
	}
	
	/**
	 * 即使是BigDecimal也会在double面前栽跟斗
	 */
	public static void testDouble() {
		BigDecimal dec = new BigDecimal("5");
		double d = 0.01d;
		BigDecimal bd = new BigDecimal(d);
		System.out.println(bd);
		bd = new BigDecimal(String.valueOf(d));
		System.out.println(bd);
		dec = dec.multiply(bd);
		System.out.println(dec);
	}
	
	/**
	 * LinkedHashMap的values()方法返回的集合也是有序的
	 */
	public static void testLinkedHashMapValues() {
		Map<String, String> map = new LinkedHashMap<>();
		map.put("Zsljfd", "1");
		map.put("242", "2");
		map.put("23", "3");
		map.put("fdadf", "4");
		map.put("2f23", "5");
		for (String value : map.values()) {
			System.out.println(value);
		}
	}
	
	/**
	 * fastJSON使用get方法来获取类的域，若没有对应的get方法则会丢失这个域。
	 */
	public static void testFastJSON() {
		class TestFastJSON {
			private int field1;
			private int field2 = 2;
			public void setField1(int field1) {
				this.field1 = field1;
			}
			public void setField2(int field2) {
				this.field2 = field2;
			}
//			public int getField1() {
//				return field1;
//			}
//			public int getField2() {
//				return field2;
//			}
		}
		TestFastJSON obj = new TestFastJSON();
		System.out.println(JSON.toJSONString(obj));
		obj.setField1(1);
		System.out.println(JSON.toJSONString(obj));
	}
	
	public static void testGetStackTrace(String[] args) {
		int[] array = new int[0];
		try {
			try {
				System.out.println(array[1]);
			} catch (Exception e) {
				System.out.println(ExceptionUtils.getStackTrace(e) + "\n-----------\n");
				throw new RuntimeException(e);
			}
		} catch (Exception e) {
			System.out.println(ExceptionUtils.getStackTrace(e));
		}
	}
	
	/**
	 * 变长参数就算不传，也会产生一个长度为0的数组对象而不是null。
	 */
	public static void testVariableArgument() {
		class Va {
			void varArg(int i, String... strs) {
				if (strs == null) {
					System.out.println(">>>>strs is null");
				} else if (strs.length == 0) {
					System.out.println(">>>>strs is a empty array");
				} else {
					System.out.println(">>>>strs have values");
				}
			}
		}
		String[] array = null;
		Va va = new Va();
		va.varArg(1);
		va.varArg(1, array);
		va.varArg(2, new String[0]);
		va.varArg(3, "aaa");
	}
	
	public static void testListIterator() {
		List<String> list = new LinkedList<>();
		list.add("A");
		list.add("B");
		list.add("D");
		ListIterator<String> ite = list.listIterator();
		while (ite.hasNext()) {
			if (ite.next().equals("B")) {
				ite.add("C");
				System.out.println(ite.next());
			}
		}
		System.out.println(list);
	}
	
	/**
	 * 子类的构造器一定会先调用父类的无参构造器，即使父类的构造器是私有的也会调用到。如果没有则编译报错。
	 */
	public static void testExtendsConstructor() {
		class Father {
			private Father() {
				System.out.println("construct Father");
			}
		}
		class Child extends Father{
			public Child() {
				System.out.println("construct Child");
			}
			public Child(int i) {
				System.out.println("construct Child with param");
			}
		}
		new Child();
		new Child(1);
	}
	
	public static void testDecimal() {
		double d = 2726196558.0;
		System.out.println(d);
		System.out.println(new DecimalFormat("0.0").format(d));
		System.out.println(new DecimalFormat("#.#").format(d));
		System.out.println(new DecimalFormat("#.0####").format(d));
		System.out.println();
		d = 27.261965580;
		System.out.println(d);
		System.out.println(new DecimalFormat("0.0").format(d));
		System.out.println(new DecimalFormat("#.#").format(d));
		System.out.println(new DecimalFormat("#.####").format(d));
		System.out.println();
		d = 5258027.2236196;
		System.out.println(d);
		System.out.println(new DecimalFormat("0.0").format(d));
		System.out.println(new DecimalFormat("#.#").format(d));
		System.out.println(new DecimalFormat("#.####").format(d));
	}
	
	public static void testFlowApi() {
		List<String> row = new ArrayList<>(24);
		for (int i=0; i< 24; i++) {
			row.add("1");
		}
		row.set(0, "20180101000000");
		row.set(3, "20180101000000");
		row.set(17, "20180101000000");
		row.set(21, "20180101000000");
		List<List<String>> datas = new ArrayList<>();
		datas.add(row);
		Map<String, Object> map = new HashMap<>();
		map.put("jobId", "5bd064873c7b9d7e0c865c13");
		map.put("datas", datas);
		String body = JSON.toJSONString(map);
		String url = "http://localhost:8012/uiTest/handleJobWithInsertData";
		Map<String, String> headers = new HashMap<>();
		headers.put("Content-Type", "application/json");
		System.out.println(HttpClientUtil.post(url, body, headers));
	}
	
	public static void testAbstractPriorityConsumerQueue() {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		int size = 20;
		AbstractConsumerQueue<Integer> queue =
				new AbstractPriorityConsumerQueue<Integer>(size - (HardwareVariables.CPU_THREAD_NUM+1)) {
					protected void process(Integer element) {
						String start = df.format(new Date()).substring(17);
						//稍微错开，避免同时领取任务。
						GeneralUtil.sleep(1000 + new Random().nextInt(100));
						System.out.println(element + "\t" + start + " - "
								+ df.format(new Date()).substring(17));
					}
				};
		Set<Integer> set = new HashSet<Integer>(20);
		Random random = new Random();
		while (set.size() < size) {
			int e = random.nextInt(1000);
			set.add(e);
		}
		for (Integer e : set) {
			queue.pushIntoQueue(e);
		}
	}
	
	/**
	 * 子类会优先调自己的方法，即使是从父类的入口发起调用，如果在内部又调用到其它方法时，只要子类自己有就会替换成自己的。
	 * 但前提是子类的这个方法是对父类可见的，若为子类私有，则父类仍会调自己的方法。
	 */
	public static void testOverwriting() {
		class Father {
			void functionA() {
				System.out.println("invoke Father A");
				functionB();
			}
			private void functionB() {
				System.out.println("invoke Father B");
				functionC();
				functionD();
			}
			void functionC() {
				System.out.println("invoke Father C");
			}
			protected void functionD() {
				System.out.println("invoke Father D");
			}
		}
		class Children extends Father {
			private void functionB() {
				System.out.println("invoke Children B");
				functionC();
				functionD();
			}
			void functionC() {
				System.out.println("invoke Children C");
			}
			protected void functionD() {
				System.out.println("invoke Children D");
			}
		}
		Children children = new Children();
		children.functionA();
	}
	
	/**
	 * BigDecimal使用equals方法时，不仅比较值，而且比较精度。
	 */
	public static void testBigDecimalEquals() {
		System.out.println(new BigDecimal("2.200").equals(new BigDecimal("2.200")));
		System.out.println(new BigDecimal("2.200").equals(new BigDecimal("2.20")));
	}
	
	public static void testPayApi() {
		String url = "http://101.200.123.157:7000/skypay/alipay";
		Map<String, String> map = new HashMap<String, String>();
//		map.put("pid", "5002");
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		list.add(map);
		String params = WebUtil.createJsonFromListMap(list);
		params = params.substring(1, params.length()-1);
		String result = HttpClientUtil.post(url, map);
		System.out.println(result);
	}
	
	public static void testCertyfiyApi() throws IOException {
		Map<String, String> map = new HashMap<String, String>();
//		map.put("name", "熊书清");
//		map.put("phoneNo", "13671202039");
//		map.put("idCardNo", "420607197301244111");
		map.put("name", "朱泽湘");
		map.put("phoneNo", "18163968938");
		map.put("idCardNo", "430381199111156012");
		map.put("driverId", "20846");
		String result = HttpClientUtil.post("http://localhost:8081/RiskControl/certifiyCtrl/certifiyDriverData.do", map);
//		String result = HttpClientUtil.post("http://120.133.0.170:8081/RiskControl/certifiyCtrl/certifiyDriverData.do", map);
//		String result = HttpClientUtil.get("http://localhost:8081/RiskControl/certifiyCtrl/getDriverCertifiyDetail.do", map);
//		String result = HttpClientUtil.get("http://120.133.0.170:8081/RiskControl/certifiyCtrl/clearAllDriverCert.do?includeCertied=true", null);
		System.out.println(result);
	}
	
	/**
	 * 似乎不限于8192？
	 */
	public static void testBufferSize() {
		String file = "C:/Users/zhuzx/Desktop/testBufferSize.jpg";
		try {
			URL url = new URL("http://43.241.215.77/pics/8xcar1503465742719.jpg");
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			conn.setConnectTimeout(3*1000);
			//防止屏蔽程序抓取而返回403错误
			conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
			InputStream in = conn.getInputStream();
			OutputStream out = new FileOutputStream(file);
			byte[] buffer = new byte[8193];
			int len;
			while ((len = in.read(buffer)) >= 0) {
				out.write(buffer, 0, len);
			}
			in.close();
			out.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	public static void testStringAppender() {
		try {
			System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
			Connection conn = DriverManager.getConnection(
					"jdbc:mysql://120.133.0.174:3307/fmall?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull",
					"query", "qureybyno");
			List<Map<String,String>> list = JdbcUtil.executeQuery("select * from car_driver limit 10", conn);
			String json = WebUtil.createJsonFromListMap(list);
			System.out.println(json.length());
			list = WebUtil.createListMapFromJsonArray(json);
			System.out.println(list.get(0));
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public static void testArrayComponentType() {
		String[][] array = (String[][]) Array.newInstance(String[].class, 10);
		array[0] = new String[]{"1","sdkfj"};
		System.out.println(Arrays.deepToString(array));
		System.out.println(array.getClass().getComponentType());
		System.out.println(new int[2].getClass().getComponentType());
	}
	
	public static void testParameterizedType() {
		List<String> list = new ArrayList<String>();
		ParameterizedType parameterizedType = (ParameterizedType) list.getClass().getGenericSuperclass();
		Type[] types = parameterizedType.getActualTypeArguments();
		System.out.println(Arrays.toString(types));
	}
	
	/**
	 * 空格以及其它空白符不能出现在url中（首位也不行，报505 HTTP Version Not Supported），必须转码（首位有空格转码后依旧会报错），中文可以。
	 * SpringMVC支持空格url。
	 */
	public static void testSpecParamForHttpRequest() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("aaa", "AAAAAAA");
		map.put("bbb", "BBBBBBB");
		map.put("ccc", "C{CCC}C\" .");
		map.put("ddd", "朱 三");
		try {
//			String result = NetUtil.get("http://localhost:8081/RiskControl/redirectCtrl/testGet.do?name=名 字", map, null);
			String result = NetUtil.get("http://localhost:8081/RiskControl/redirectCtrl/test Space.do", map, null);
//			String result = NetUtil.post("http://localhost:8081/RiskControl/redirectCtrl/testPost.do?name=名字", map.toString(), null);
			System.out.println(result);
		} catch (IOException e) {
			ExceptionUtil.handle(e);
		}
	}
	
	/** 更新值时不会更新链表，顺序不变。 */
	public static void testLinkedHashMapUpdate() {
		Map<String, String> map = new LinkedHashMap<String, String>();
		map.put("aa", "A");
		map.put("bb", "B");
		map.put("cc", "C");
		map.put("dd", "D");
		System.out.println(map);
		map.put("dd", "DD");
		map.put("bb", "BB");
		System.out.println(map);
	}
	
	public static void testSplitByString() {
//		String s = "ATATATATs"
//				+ "seATATATATauiuoATATATor"
//				+ "eawATATATAT";
//		System.out.println(s.length());
//		System.out.println(s);
//		System.out.println(Arrays.toString(GeneralUtil.splitByStringHighPerformance(s, "AT")));
//		System.out.println(Arrays.toString(GeneralUtil.splitByStringHighPerformance(s, "ATA")));
//		System.out.println(Arrays.toString(GeneralUtil.splitByStringHighPerformance(s, "ATAT")));
//		System.out.println(Arrays.toString(GeneralUtil.splitByStringHighPerformance(s, "ATATA")));
//		System.out.println(Arrays.toString(GeneralUtil.splitByStringHighPerformance(s, "ATATAT")));
	}
	
//	public static void testCreateExcel() {
//		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
//		Map<String,String> map = new HashMap<String,String>();
//		map.put("aaa", "AAA");
//		map.put("bbb", "BBB");
//		map.put("ccc", "CCC");
//		map.put("ddd", "DDD");
//		list.add(map);
//		map = new HashMap<String,String>();
//		map.put("aaa", "AAAAAA");
//		map.put("bbb", "BBBBBB");
//		map.put("ccc", "CCCCCC");
//		map.put("ddd", "DDDDDD");
//		list.add(map);
//		Workbook wb = ExcelUtil.createExcel(true, new String[]{"aSheet","bSheet"}, list, list);
//		
//		String fileName = "testexcel";
//		String exportFilePath = "C:\\Users\\zhuzx\\Desktop";
//		String filePath = exportFilePath + "/" + fileName + ".xlsx";
//		try {
//			wb.write(new FileOutputStream(filePath));
//		} catch (IOException e) {}
//		
//		List<Map<String,String>> temp = ExcelResolver.createListMapFromExcelSheet(wb.getSheetAt(0));
//		for (Map<String, String> map2 : temp) {
//			System.out.println(map2);
//		}
//	}

	/**
	 * 简单测试，调度线程池只能同时运行一个任务；一个调度任务失败不影响其它的调度指令，但该调度会停止；被关闭后不可再用。
	 */
	public static void testScheduledExecutorService() {
		ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
		DateFormat df = new SimpleDateFormat("mm:ss");
		Runnable task1 = new Runnable() {
			public void run() {
				System.out.println(df.format(new Date()) + " task1 running");
				System.out.println(df.format(new Date()) + " task1 throw a exception");
				throw new RuntimeException("task1 rte");
			}
		};
		ses.scheduleAtFixedRate(task1, 2, 2, TimeUnit.SECONDS);
		Runnable task2 = new Runnable() {
			public void run() {
				System.out.println(df.format(new Date()) + " task2 beging");
				GeneralUtil.sleep(2 * 1000);
				System.out.println(df.format(new Date()) + " task2 end");
			}
		};
		ses.scheduleWithFixedDelay(task2, 1, 1, TimeUnit.SECONDS);
		Runnable task3 = new Runnable() {
			public void run() {
				System.out.println(df.format(new Date()) + " task3 beging");
				GeneralUtil.sleep(2 * 1000);
				System.out.println(df.format(new Date()) + " task3 end");
			}
		};
		ses.scheduleWithFixedDelay(task3, 1, 1, TimeUnit.SECONDS);
		try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
		}
		ses.shutdown();
		try {
			System.out.println(df.format(new Date()) + "停止后再尝试重新启动");
			Thread.sleep(3000);
		} catch (InterruptedException e) {
		}
		ses.scheduleAtFixedRate(task1, 1, 1, TimeUnit.SECONDS);
		try {
			Thread.sleep(6000);
		} catch (InterruptedException e) {
		}
		ses.shutdown();
	}
	
	/**
	 * double类型无法声明过长的数字，而可以赋予。实际精度有限（即使没有溢出）。
	 */
	public static void testDoubleScale() {
//		double error = 20170426235959;
		String time = "20170426235959";
		double num = Double.parseDouble(time);
		System.out.println(time);
		System.out.println(num);
		System.out.println(new BigDecimal(num).toPlainString());
		System.out.println();
		time += time;
		num = Double.parseDouble(time);
		System.out.println(time);
		System.out.println(num);
		System.out.println(new BigDecimal(num).toPlainString());
	}
	
	public static void testLexicographically() {
		System.out.println("111.111".compareTo("11.1111"));
		System.out.println("111.111".compareTo("1111.11"));
		System.out.println("111.1111111".compareTo("1111.11"));
		System.out.println(".".compareTo("0"));
		System.out.println("111".compareTo("222"));
		System.out.println("11111".compareTo("222.2"));
	}
	
	public static void testIso() {
		for (byte b=Byte.MIN_VALUE; ; b++) {
			byte[] bytes = new byte[] {b};
			String c = new String(bytes, StandardCharsets.ISO_8859_1);
			System.out.println(b + ":\t" + c);
			if (b==Byte.MAX_VALUE) break;
		}
	}
	
	/**
	 * GBK似乎兼容ISO，但可能会多出问号。
	 */
	public static void testIsoGbkUtf() {
		String iso;
		byte[] bytes;
		String returnToIso;
		
		iso = "æ±æ³½æ¹çäºä¸ä¹ä¹ä¸å¹´æ¹æ½­äººæ° ÖìÔóÏæÉúÓÚÒ»¾Å¾ÅÒ»ÄêÏæÌ¶ÈËÊÏ";
		System.out.println("iso:" + iso);
		bytes = iso.getBytes(StandardCharsets.ISO_8859_1);
		System.out.println("isoArray:" + Arrays.toString(bytes));
		String utf = new String(bytes, StandardCharsets.UTF_8);
		System.out.println("utf:" + utf);
		bytes = utf.getBytes(StandardCharsets.UTF_8);
		System.out.println("utfArray:" + Arrays.toString(bytes));
		returnToIso = new String(bytes, StandardCharsets.ISO_8859_1);
		System.out.println("Iso:" + returnToIso);
		
		System.out.println();
		System.out.println("iso:" + iso);
		bytes = iso.getBytes(StandardCharsets.ISO_8859_1);
		System.out.println("isoArray:" + Arrays.toString(bytes));
		String gbk = new String(bytes, Charset.forName("GBK"));
		System.out.println("gbk:" + gbk);
		bytes = gbk.getBytes(Charset.forName("GBK"));
		System.out.println("gbkArray:" + Arrays.toString(bytes));
		returnToIso = new String(bytes, StandardCharsets.ISO_8859_1);
		System.out.println("Iso:" + returnToIso);
		
		System.out.println();
		iso = "[{\"key\":000, \"name\":\"朱泽湘222生于æ一九¹çäºä¸ä¹ä¹ä¸å¹´æ¹æ½九一年ÂÂÃ¤ÂºÂ湘潭人氏aaabc±æ³3äbbccc";
		System.out.println(iso);
		bytes = iso.getBytes(StandardCharsets.UTF_8);
		System.out.println(bytes.length);
		String temp = new String(bytes, StandardCharsets.ISO_8859_1);
		System.out.println(temp);
		bytes = temp.getBytes(StandardCharsets.ISO_8859_1);
		System.out.println(bytes.length);
		temp = new String(bytes, StandardCharsets.UTF_8);
		System.out.println(temp);
		System.out.println(temp.getBytes(StandardCharsets.UTF_8).length);
	}
	
	/**
	 * 书面形式初始化数组，最后多出一个逗号会被无视，不会导致多出一个空的尾元素。
	 */
	public static void testArrayLength() {
		String[] specificCodes = new String[] {
				"aaa",
				"bbb",
		};
		System.out.println(specificCodes.length);
	}
	
	/**
	 * 不能以UTF-8格式字符串存储压缩后的数据，如果必须要以字符串存储，须用ISO-8859-1。
	 */
	public static void testGzipCompress() {
		String original = "aaa三重复重复";
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			GZIPOutputStream gzipOut = new GZIPOutputStream(out);
			gzipOut.write(original.getBytes(
					StandardCharsets.UTF_8
					));
			gzipOut.close();
			String temp = null;
			temp = out.toString();
			System.out.println("no >>" + temp);
			System.out.println(Arrays.toString(out.toByteArray()));
			
			temp = out.toString("ISO-8859-1");
			System.out.println("\nISO>>" + temp);
			System.out.println(Arrays.toString(temp.getBytes("ISO-8859-1")));
			
			temp = out.toString("UTF-8");
			System.out.println("\nUTF>>" + temp);
			System.out.println(Arrays.toString(temp.getBytes("UTF-8")));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * getBytes方法默认以UTF-8编码，new String方法也是UTF-8。<br>
	 * UTF-8三字节存汉字，GBK两字节。<br>
	 * GBK编码序列以UTF-8解码后固然乱码，但重新将此乱码以UTF-8编码后，得到的已经是另一个字节序列。反之也是。<br>
	 * UTF-8以单字节存储ASCII码。<br>
	 */
	public static void testEncodingStorage() {
		byte[] bytes = "强".getBytes();
		System.out.println(Arrays.toString(bytes));
		System.out.println(Arrays.toString("强".getBytes(StandardCharsets.UTF_8)));
		String iso = new String(Arrays.copyOf(bytes, 2), StandardCharsets.ISO_8859_1);
		System.out.println("iso: " + iso);
		System.out.println("isoArray: " + Arrays.toString(iso.getBytes(StandardCharsets.ISO_8859_1)));
		System.out.println("isoToUtfArray: " + Arrays.toString(iso.getBytes(StandardCharsets.UTF_8)));
		
		String gbk = new String(Arrays.copyOf(bytes, 2), Charset.forName("GBK"));
		System.out.println("\ngbk: " + gbk);
		byte[] gbkArray = gbk.getBytes(Charset.forName("GBK"));
		System.out.println("gbkArray: " + Arrays.toString(gbkArray));
		System.out.println("gbkToUtfArray: " + Arrays.toString(gbk.getBytes()));
		String gbkArrayToUtf = new String(gbkArray, StandardCharsets.UTF_8);
		System.out.println("gbkArrayToUtf: " + gbkArrayToUtf);
		System.out.println("gbkArrayToUtfArray: " + Arrays.toString(gbkArrayToUtf.getBytes(StandardCharsets.UTF_8)));
		System.out.println("utfToGbkArray: " + Arrays.toString(gbkArrayToUtf.getBytes(Charset.forName("GBK"))));
		System.out.println("returnToGbk: " + new String(
				gbkArrayToUtf.getBytes(StandardCharsets.UTF_8), Charset.forName("GBK")));
		
		System.out.println();
		String temp = "";
		for (byte b : bytes) {
			char error = (char) ((int) b);
			System.out.println(error);
			temp += error;
		}
		System.out.println(temp);
		byte[] newBytes = temp.getBytes();
		System.out.println(Arrays.toString(newBytes));
		System.out.println(Arrays.toString("ABC".getBytes()));
		
		System.out.println();
		bytes = "额".getBytes(StandardCharsets.UTF_8);
		System.out.println(new String(bytes));
		System.out.println(Arrays.toString(bytes));
		String gbkTest = new String(bytes, Charset.forName("GBK"));
		System.out.println("gbkTest: " + gbkTest);
		byte[] gbkTestArray = gbkTest.getBytes(Charset.forName("GBK"));
		System.out.println(Arrays.toString(gbkTestArray));
		String returnToUtf = new String(gbkTestArray, StandardCharsets.UTF_8);
		System.out.println("returnToUtf: " + returnToUtf);
	}
	
	public static void testGetMessage() {
		try {
			System.out.println(new SimpleDateFormat("yyyy/MM/dd").parse("2011-8/1"));
		} catch (ParseException e) {
			System.out.println(e.getMessage());
		}
		try {
			String s = null;
			System.out.println(s.substring(2));
		} catch (Exception e) {
			String msg = e.getMessage();
			System.out.println(msg);
		}
	}
	
	public static void testRegexBracketEscaped() {
		String regex = "skfdj}sjfdksdjfds";
		Pattern pat = Pattern.compile(regex);
		System.out.println(pat);
		pat = Pattern.compile("lsfdjs}}}}}lfjklskfj");
		System.out.println(pat);
		//pat = Pattern.compile("lsf{2}jadsfad{adfsdf");
		System.out.println(pat);
	}
	
	public static void testClipboardLineSeparator() {
		String inputValue = JOptionPane.showInputDialog("请输入：");
		char[] chars = new char[inputValue.length()];
		inputValue.getChars(0, inputValue.length(), chars, 0);
		for (char c : chars) {
			System.out.println((int) c);
		}
		System.out.println((int) ' ');
	}
	
	public static void testBigDecimal() {
		BigDecimal num = new BigDecimal("3.15456465E333");
		System.out.println(num.toString());
		System.out.println(num.toEngineeringString());
		System.out.println(num.toPlainString());
	}
	
	public static void testStringInstance() {
		String s = ",";
		String s2 = ",";
		System.out.println(s == ",");
		System.out.println(s == s2);
	}
	
	public static void testDateCompareMethodReturn() throws ParseException {
		Date startDate = dafDate.parse("2015-10-10");
		Date endDate = dafDate.parse("2015-11-11");
		System.out.println(endDate.compareTo(startDate));
		Calendar startCal = new GregorianCalendar();
		startCal.setTime(startDate);
		Calendar endCal = new GregorianCalendar();
		endCal.setTime(endDate);
		System.out.println(endCal.compareTo(startCal));
	}
	
	public static void testPath(String[] args) throws IOException {
		Path path = Paths.get("storage/data.sto");
		if (!Files.exists(path)) {
			Files.createDirectory(path.getParent());
			Files.createFile(path);
		}
		Files.write(path, "aaa".getBytes());
		System.out.println(new String(Files.readAllBytes(path)));
	}
	
	/**
	 * 父类会访问自己的属性，而不是子类的属性，即使是由子类发起的调用。
	 */
	public static void testOverride() {
		class Father {
			private String id = "father";
			public void printIdA() {
				System.out.println("A:" + id);
			}
			public void printIdB() {
				System.out.println("B:" + id);
			}
		}
		class Child extends Father {
			private String id = "child";
			public void printIdB() {
				super.printIdB();
				System.out.println("B:" + id);
			}
		}
		Child c = new Child();
		c.printIdA();
		c.printIdB();
	}
	
	public static void testPriorityQueueLimit() {
		BlockingQueue<String> queue = new PriorityBlockingQueue<String>(5);
		for (int i=1; i<9; i++) {
			queue.add(String.valueOf(i));
		}
		System.out.println(queue);
		queue = new ArrayBlockingQueue<String>(5);
		for (int i=1; i<8; i++) {
			queue.add(String.valueOf(i));
		}
		System.out.println(queue);
		queue.add("1");
		queue.add("0");
		try {
			System.out.println(queue.take());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static void testBitOperation() {
		int i = 13;
		System.out.println(i + ":\t" + Integer.toBinaryString(i));
		i = i >> 1;
		System.out.println(i + ":\t" + Integer.toBinaryString(i));
		i = i >> 2;
		System.out.println(i + ":\t" + Integer.toBinaryString(i));
		i = i << 1;
		System.out.println(i + ":\t" + Integer.toBinaryString(i));
		i = i << 3;
		System.out.println(i + ":\t" + Integer.toBinaryString(i));
		i = i >> 1;
		System.out.println(i + ":\t" + Integer.toBinaryString(i));
		i = i >> 2;
		System.out.println(i + ":\t" + Integer.toBinaryString(i));
		i = 7;
		int bitNum = (1 << i) - 1;
		System.out.println(i + ":\t" + Integer.toBinaryString(bitNum));
		i = bitNum >> 6;
		System.out.println(i + ":\t" + Integer.toBinaryString(i));
		i = i >> 3;
		System.out.println(i + ":\t" + Integer.toBinaryString(i));
	}
	
	public static void testMXBean() {
		OperatingSystemMXBean osmxb = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
		System.out.println(osmxb.getTotalSwapSpaceSize());
		System.out.println(osmxb.getFreeSwapSpaceSize());
		System.out.println(osmxb.getTotalPhysicalMemorySize());
		System.out.println(osmxb.getFreePhysicalMemorySize());
	}
	
	public static void testDirectByteBuffer() {
		System.out.println("start");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//Integer.MAX_VALUE = 2GB - 1
		ByteBuffer buffer = ByteBuffer.allocateDirect(1024*1024*1024);
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		DirectBuffer db = (DirectBuffer) buffer;
		db.cleaner().clean();
		System.out.println("end");
	}
	
	public static void testMapNullKey() {
		Map<String,String> map = new HashMap<String,String>();
		map.put(null, "aaa");
		System.out.println(map.get(null));
	}
	
	public static void testSystemProps() {
		try {
			Properties props = System.getProperties();
			System.out.println(props.getProperty("os.name"));
			System.out.println(props.getProperty("os.arch"));
			System.out.println(props.getProperty("os.version"));
			System.out.println(InetAddress.getLocalHost().getHostAddress());
			System.out.println("----");
			String command = "cmd.exe /c ipconfig /all";
			Process p = Runtime.getRuntime().exec(command);
			BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), Charset.forName("GBK")));
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static <E> void testGenericConstraint(E e1, E e2) {
		System.out.println("e1:" + e1.getClass().getSimpleName());
		System.out.println("e2:" + e2.getClass().getSimpleName());
	}
	
	public static void testGenericCompile() {
		testGenericConstraint(2, "a");
		System.out.println("no constraint");
	}
	
	private static String[] getStringArray() {
		String[] array = new String[] {
				"2016-08-21 11:02:51",
				"2016-09-21 11:02:51",
				"2016-09-21 12:02:51",
				"2016-09-21 12:02:52",
				"2016-10-21 12:02:51",
				"2016-12-21 01:02:51",
				"2017-01-21 01:02:51",
				"",
				" ",
				"",
				"",
				"aaaaa",
				"aaaaa.2015",
				"aaaaa.2016",
				"aaaaa.log"
		};
		return array;
	}
	
	public static void testStringComparable() {
		String[] times = getStringArray();
		for (int i=1; i<times.length; i++) {
			System.out.println("[" + times[i-1] + "] compareTo [" + times[i] + "] : "
					+ "" + times[i-1].compareTo(times[i]));
		}
	}
	
	public static void testPriorityBlockingQueue() {
		String[] strs = getStringArray();
		BlockingQueue<String> queue = new PriorityBlockingQueue<String>(Arrays.asList(strs));
		while (queue.size() > 0) {
			try {
				System.out.println("[" + queue.take() + "]");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void testEncode() throws UnsupportedEncodingException {
		String old = "ÖìÔóÏæ";
		System.out.println("old: " + old);
		String regex = "^[\u4E00-\u9FA5]+$";
		System.out.println(old.matches(regex));
		
		String utf = new String(old.getBytes("ISO8859-1"), "UTF-8");
		System.out.println("utf-8: " + utf);
		System.out.println(utf.matches(regex));
		
		String gbk = new String(old.getBytes("ISO8859-1"), "GBK");
		System.out.println("gbk: " + gbk);
		System.out.println(gbk.matches(regex));
		gbk = new String(old.getBytes("GBK"), "UTF-8");
		System.out.println("gbk: " + gbk);
		
		System.out.println();
		old = "朱泽湘";
		System.out.println("old: " + old);
		utf = new String(old.getBytes("ISO8859-1"), "UTF-8");
		System.out.println("utf-8: " + utf);
		utf = new String(old.getBytes("GBK"), "UTF-8");
		System.out.println("utf-8: " + utf);
		gbk = new String(old.getBytes("ISO8859-1"), "GBK");
		System.out.println("gbk: " + gbk);
		gbk = new String(old.getBytes("UTF-8"), "GBK");
		System.out.println("gbk: " + gbk);
		
		System.out.println(Arrays.toString(old.getBytes()));
		System.out.println(Arrays.toString(old.getBytes("UTF-8")));
		System.out.println(Arrays.toString(old.getBytes("GBK")));
		System.out.println(Arrays.toString(old.getBytes("ISO8859-1")));
		
		System.out.println("\nold: " + old);
		String iso8859 = new String(old.getBytes("UTF-8"), "ISO8859-1");
		System.out.println("iso8859: " + iso8859);
		String generated = new String(iso8859.getBytes("ISO8859-1"), "UTF-8");
		System.out.println("generated: " + generated);
		System.out.println("generated equals gbk ? " + generated.equals(
				new String("ÖìÔóÏæ".getBytes("ISO8859-1"), "GBK")));
		generated = new String(iso8859.getBytes("ISO8859-1"), "GBK");
		System.out.println("generated: " + generated);
		
		System.out.println();
		iso8859 = new String(old.getBytes("ISO8859-1"), "ISO8859-1");
		System.out.println("iso8859 2: " + iso8859);
		generated = new String(iso8859.getBytes("ISO8859-1"), "UTF-8");
		System.out.println("generated: " + generated);
		generated = new String(iso8859.getBytes("ISO8859-1"), "GBK");
		System.out.println("generated: " + generated);
		
		System.out.println();
		String encodeStr = URLEncoder.encode(old, "ISO8859-1");
		System.out.println(encodeStr);
		encodeStr = URLDecoder.decode(encodeStr, "ISO8859-1");
		System.out.println(encodeStr);
	}
	
	public enum TestEnum {
		A("aa"),B("bb");
		private String field;
		private TestEnum(String field) {
			this.field = field;
			System.out.println("initialize eunm " + this);
		}
		public String getField() {
			return this.field;
		}
		static {
			System.out.println("initialize static code block");
		}
		public static final TestEnum[] enums = TestEnum.values();
		public static final String[] fields = getFields();
		public static String[] getFields() {
			System.out.println("initialize static variable");
			return new String[] {A.getField(), B.getField()};
		}
	}
	
	public static void testInitializeOrder() {
		System.out.println(Arrays.toString(TestEnum.fields));
	}
	
	public static void testDateFormat() throws ParseException {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
		System.out.println(dateFormat.format(dateFormat.parse("2016-10-10 10:10:10.111").getTime()));
		
		dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		System.out.println(dateFormat.format(dateFormat.parse("2016-10-10 10:10:10.2").getTime()));
		
		dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
		System.out.println(dateFormat.format(dateFormat.parse("2016-10-10 10:10:10.3").getTime()));
		
		dateFormat = new SimpleDateFormat("yyyy*MM*dd*HH*mm*ss");
		System.out.println(dateFormat.format(dateFormat.parse("2016*10*10*10*10*10").getTime()));
		
		dateFormat = new SimpleDateFormat(null);
	}
	
	@SuppressWarnings("deprecation")
	public static void testDateParse() {
		String str0 = new Date().toString();
		String str1 = "2016-10-10 10:10:10";
		String str2 = "2016-10-10";
		String str3 = "10:10:10";
		String str4 = "20161010";
		Date date = new Date(str0);
		System.out.println(date);
		date = new Date(str1);
		System.out.println(date);
		date = new Date(str2);
		System.out.println(date);
		date = new Date(str3);
		System.out.println(date);
		date = new Date(str4);
		System.out.println(date);
	}
	
	public static void testListModification() {
		List<Map<String,String>> list = new ArrayList<Map<String,String>>();
		Map<String,String> map1 = new HashMap<String,String>();
		map1.put("key", "aaa");
		Map<String,String> map2 = new HashMap<String,String>();
		map2.put("key", "bbb");
		list.add(map1);
		list.add(map2);
		System.out.println(list);
		
		for (Map<String,String> map : list) {
			list.remove(map);
		}
		System.out.println(list);
		
		list.clear();
		list.add(map1);
		list.add(map2);
		for (int i=0; i<list.size(); i++) {
			list.remove(list.get(i));
		}
		System.out.println(list);
		
		list.clear();
		list.add(map1);
		list.add(map2);
		for (int i=list.size()-1; i>=0; i--) {
			list.remove(list.get(i));
		}
		System.out.println(list);
		
		list.clear();
		list.add(map1);
		list.add(map2);
		for (int i=0; i<list.size(); i++) {
			list.set(i, null);
		}
		System.out.println(list);
	}
	
	public static void testExceptionReturn() {
		try {
			String s = null;
			s.length();
		} catch (Exception e) {
			System.out.println("[NullPointer:]\n" + e.getMessage() + "\n"
					+ e.getClass().getSimpleName() + "\n"
					+ Arrays.toString(e.getStackTrace()) + "\n");
			try {
				String s = "";
				s.charAt(0);
			} catch (Exception ex) {
				System.out.println("[OutOfRange:]\n" + ex.getMessage() + "\n"
						+ ex.getClass().getSimpleName() + "\n"
						+ Arrays.toString(ex.getStackTrace()) + "\n");
			}
		}
		try {
			new SimpleDateFormat("aa23a").parse("sldfjkd");
		} catch (Exception e) {
			e.printStackTrace();
			String msg = ExceptionUtil.describe(e, SandBox.class);
			System.out.println(msg);
		}
	}
	
	public static void testHashCode() {
		System.out.println("aaa".hashCode());
		System.out.println("fffffffffff".hashCode());
		System.out.println("bb".hashCode());
		System.out.println("2016-08-21 11:02:51".hashCode());
		System.out.println("2016-09-21 11:02:51".hashCode());
		System.out.println("2016-09-21 12:02:51".hashCode());
		System.out.println("2016-09-21 12:02:52".hashCode());
		System.out.println("2016-10-21 12:02:51".hashCode());
		System.out.println("ss".hashCode());
		System.out.println("ea".hashCode());
		System.out.println("nab".hashCode());
	}
	
	public static void testMapEquals() {
		Map<String,String> map1 = new HashMap<String,String>();
		map1.put("1", "1");
		map1.put("2", "2");
		map1.put("3", "3");
		Map<String,String> map2 = new HashMap<String,String>();
		map2.put("1", "1");
		map2.put("2", "2");
		map2.put("3", "3");
		System.out.println(map1.equals(map2));
		map2.put("3", "2");
		System.out.println(map1.equals(map2));
	}
	
	public static void testMapIterator() {
		Map<String,String> map = new HashMap<String,String>();
		map.put("1", "1");
		map.put("2", "2");
		map.put("3", "3");
		System.out.println(map);
		Iterator<String> ite = map.keySet().iterator();
		while (ite.hasNext()) {
			String key = ite.next();
			if (key.equals("2")) {
				ite.remove();
			}
		}
		System.out.println(map);
		
		map = new ConcurrentHashMap<String,String>(map);
		for (String s : map.keySet()) {
			if (s.equals("3")) {
				map.remove(s);
			}
		}
		System.out.println(map);
		
		map = new HashMap<String,String>();
		map.put("1", "1");
		System.out.println(map);
		for (Map.Entry<String, String> entry : map.entrySet()) {
			if (entry.getKey().equals("1")) map.remove(entry.getKey());
		}
		System.out.println(map);
		
		map = new HashMap<String,String>();
		map.put("1", "1");
		map.put("2", "2");
		map.put("3", "3");
		for (Map.Entry<String, String> entry : map.entrySet()) {
			if (entry.getKey().equals("1")) map.remove(entry.getKey());
		}
		System.out.println(map);

		map = new HashMap<String,String>();
		map.put("1", "1");
		map.put("2", "2");
		map.put("3", "3");
		for (Map.Entry<String, String> entry : map.entrySet()) {
			if (entry.getKey().equals("3")) map.remove(entry.getKey());
		}
		System.out.println(map);
	}
	
	public static void testBinarySearch() {
		int[] values = new int[] {1,2,4,6,7};
		System.out.println(Arrays.binarySearch(values, 1));
		System.out.println(Arrays.binarySearch(values, 6));
		System.out.println(Arrays.binarySearch(values, 5));
		System.out.println(Arrays.binarySearch(values, 9));
	}
	
	public static final DateFormat daf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static final DateFormat dafDate = new SimpleDateFormat("yyyy-MM-dd");
	public static final DateFormat dafTime = new SimpleDateFormat("HH:mm:ss");
	public static final DecimalFormat def = new DecimalFormat("#0.00");
	
	@Value
	private static class User {
		Integer id;
		String name;
		Integer age;
		static List<User> createDemoList() {
			List<User> data = new ArrayList<>();
			data.add(new User(1, "金大", 23));
			data.add(new User(2, "银二", 65));
			data.add(new User(3, "张三", 57));
			data.add(new User(4, "李四", 45));
			data.add(new User(5, "王五", 11));
			data.add(new User(6, "赵六", 32));
			data.add(new User(7, "钱七", 5));
			data.add(new User(8, "宋八", 64));
			return data;
		}
	}
	
}